Namespace("sketch.ui");

(function(fwk, ui, cmd) {
    ui.ViewObserver = klass(null, {

        _constructor: function(propertyDesigner, actionDesigner){
            this._propertyDesigner = propertyDesigner;
            this._actionDesigner = actionDesigner;
            this._onElementSelected = EventHandler(this, this.onElementSelected);
            this._onElementClicked = EventHandler(this, this.onElementClicked);
        },

        setupViewCommand: function(view, shortcut, commandConstructor, category, image){
            this._viewCommands.push({
                view: view,
                shortcut: shortcut,
                commandConstructor: commandConstructor,
                image: image,
                category: category
            });

            ui.keyboard.addCommandShortcut(view.parent, shortcut, commandConstructor);
        },

        attach: function(view){
            var that = this;
            this._viewCommands = [];
            this._view = view;

            view.onElementSelected.bind(this._onElementSelected);
            view.onElementClicked.bind(this._onElementClicked);

            this.setupViewCommand(view, "Ctrl+C", function(){ return new cmd.Copy(view.getSelection()) },
                "Editing", "/img/ui/copy.png");
            this.setupViewCommand(view, "Ctrl+V", function(){ return new cmd.Paste(view.selectedElement()) },
                "Editing", "/img/ui/paste.png");
            this.setupViewCommand(view, "Ctrl+X", function(){ return new cmd.Cut(view.getSelection()) },
                "Editing", "/img/ui/cut.png");
            this.setupViewCommand(view, "Delete", function(){ return new cmd.Delete(view.getSelection(), that._propertyDesigner, that._actionDesigner) },
                "Editing", "/img/ui/delete.png");
            this.setupViewCommand(view, "Ctrl+D", function(){ return new cmd.Duplicate(view.getSelection()) },
                "Editing", "/img/ui/duplicate.png");

            this.setupViewCommand(view, "Ctrl+Shift+Up", function(){ return new cmd.ChangeZOrder(view.getSelection(), "front") },
                "Layering", "/img/ui/bring-to-front.png");
            this.setupViewCommand(view, "Ctrl+Shift+Down", function(){ return new cmd.ChangeZOrder(view.getSelection(), "back") },
                "Layering", "/img/ui/send-to-back.png");
            this.setupViewCommand(view, "Ctrl+Up", function(){ return new cmd.ChangeZOrder(view.getSelection(), "forward") },
                "Layering", "/img/ui/bring-forward.png");
            this.setupViewCommand(view, "Ctrl+Down", function(){ return new cmd.ChangeZOrder(view.getSelection(), "backward") },
                "Layering", "/img/ui/send-backward.png");

            ui.keyboard.addCommandShortcut(view.parent, "Left", function(){
                return new cmd.Move(view.getSelection(), "left");
            });
            ui.keyboard.addCommandShortcut(view.parent, "Right", function(){
                return new cmd.Move(view.getSelection(), "right");
            });
            ui.keyboard.addCommandShortcut(view.parent, "Up", function(){
                return new cmd.Move(view.getSelection(), "up");
            });
            ui.keyboard.addCommandShortcut(view.parent, "Down", function(){
                return new cmd.Move(view.getSelection(), "down");
            });
            ui.keyboard.addShortcut(view.parent, "Ctrl+Z", function(){
                if (fwk.commandManager.canUndo()) {
                    fwk.commandManager.undoPrevious();
                }
            });
            ui.keyboard.addShortcut(view.parent, "Ctrl+Y", function(){
                if (fwk.commandManager.canRedo()){
                    fwk.commandManager.redoNext();
                }
            });
        },
        detach: function(view){
            this._view = null;
            view.onElementSelected.unbind(this._onElementSelected);
            view.onElementClicked.unbind(this._onElementClicked);
            //TODO: unbind shortcuts
        },

        onElementClicked: function(eventData){
            if (ui.keyboard.modifiers.is({ctrl: true})){
                this._view.selectionMode("add");
                this._view.makeSelection([eventData.element]);
                this._view.selectionMode("new");

                eventData.handled = true;
            }
        },
        onElementSelected: function(element){
            if (element === null){
                this._propertyDesigner.clear();
                this._actionDesigner.clear();
                return;
            }

            this._propertyDesigner.update(element);

            var bag = new fwk.ActionBag();

            each(this._viewCommands, function(c){
                bag.add(c.category, c.commandConstructor, c.image);
            });

            var elementBag = element.getVisualActions();
            if (elementBag){
                bag.mergeWith(elementBag);
            }

            this._actionDesigner.update(bag);
        }
    });
})(sketch.framework, sketch.ui, sketch.commands);